﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using HAF.FoundationLib;
using Newtonsoft.Json;
using WareDealer.Helper;
using WareDealer.Mode;

namespace WareDealer.Works
{
    /// <summary>
    /// 价格采集任务
    /// </summary>
    [DisplayName("价格采集工作项")]
    public class JdPriceWork : IWorkItem
    {
        /// <summary>
        /// 编号
        /// </summary>
        public int ID { get; set; }
        /// <summary>
        /// 名称
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 优先级
        /// </summary>
        public int Priority { get; set; }
        /// <summary>
        /// 工作内容
        /// </summary>
        public Object WorkItems { get; set; }
        /// <summary>
        /// 状态
        /// </summary>
        public EnumGatherStatu Statu { get; internal set; }
        /// <summary>
        /// 返回结果集
        /// </summary>
        public object ResultItems { get; internal set; }

        /// <summary>
        /// 时长
        /// </summary>
        public int Time { get; set; }

        /// <summary>
        /// 执行函数
        /// </summary>
        public void ExecItem()
        {
            List<ProductInfo> wares = WorkItems as List<ProductInfo>;
            if (wares == null || wares.Count <= 0) return;
            Statu = EnumGatherStatu.Begin;
            List<string> wList = wares.Select(item => item.ProductID).ToList();
            _waresPrice.Clear();
            foreach (var item in wares)
            {
                _waresPrice.Add(new JdWarePriceCache()
                {
                    Skuid = item.ProductID,
                    LastPrice = item.ProductLastPrice,
                    TodayPrevPrice = item.ProductTodayPrice,
                    PriceTrend = item.ProductPriceTrend,
                    MinPrice = item.ProductMinPrice,
                    LastMinPrice = item.ProductMinPrice,
                    MinPriceSrc = item.ProductPriceType,
                    MaxPrice = item.ProductMaxPrice,
                    LastMaxPrice = item.ProductMaxPrice,
                    AppPrice = item.ProductMobilePrice,
                    WebPrice = item.ProductPrice,
                    QqPrice = item.ProductQQPrice,
                    WxPrice = item.ProductWXPrice,
                    IsWebChange = false,
                    IsAppChange = false,
                    IsQqChange = false,
                    IsWxChange = false,
                    PriceGatherDate = item.ProductPriceDate
                });
            }
            
            GetBatchWarePrice(wList);
        }

        private readonly List<JdWarePriceCache> _waresPrice = new List<JdWarePriceCache>();
        /// <summary>
        /// 批量价格获取
        /// </summary>
        /// <param name="pids">商品编号集合</param>
        [DisplayName("批量价格更新")]
        private void GetBatchWarePrice(List<string> pids)
        {
            Faster.XLogInfo(string.Format("批量采集价格{0}更新开始", Name));
            
            //https://pm.3.cn/prices/mgets?origin=2&skuids=1309453,1713088,1191695
            //[{"id":"1309453","p":"209.00","m":"328.00"},{"id":"1713088","p":"118.00","m":"208.00"},{"id":"1191695","p":"148.00","m":"268.00"}]
            if (pids != null && pids.Count > 0)
            {
                try
                {
                    _isWebErr = false;
                    Statu = EnumGatherStatu.Exec;
                    string skuids = string.Join(",J_", pids.ToArray());
                    //string skuids = string.Join(",", pids.ToArray());
                    //网站价格获取
                    //string url = string.Format("https://p.3.cn/prices/mgets?type=1&skuIds=J_{0}", skuids);
                    string url = "";
                    if (SysParams.AllowGetPrice)
                    {
                        url = string.Format("https://p.3.cn/prices/mgets?type=1&skuIds=J_{0}", skuids);
                        //url = string.Format("http://pm.3.cn/prices/pcpmgets?skuids={0}&origin=2&source=1&area=1_2800_4134_0&_={1}", skuids, GetTimeStamp());
                        BatchParse(url, WarePriceType.WebPrice);

                        //List<JdWarePriceCache> tmpPrices = _waresPrice.FindAll(t => t.WebPrice == 0);
                        if (_isWebErr)
                        {
                            //如果价格为0的超过10个则跑另外一个批量采集接口
                            skuids = string.Join(",", pids.ToArray());
                            url = string.Format("http://pm.3.cn/prices/pcpmgets?skuids={0}&origin=2&source=1&area=1_2800_4134_0&_={1}", skuids, Golemer.GetTimeStamp());
                            BatchParse(url, WarePriceType.WebPrice);
                        }
                        
                    }

                    skuids = string.Join(",", pids.ToArray());
                    if (SysParams.AllowGetMobilePrice)
                    {
                        //手机平台价格获取
                        url = string.Format("https://pm.3.cn/prices/mgets?origin=2&skuids={0}", skuids);
                        BatchParse(url, WarePriceType.AppPrice);
                    }

                    if (SysParams.AllowGetQQPrice)
                    {
                        //QQ平台价格获取
                        url = string.Format("https://pe.3.cn/prices/mgets?origin=4&skuids={0}", skuids);
                        BatchParse(url, WarePriceType.QQPrice);
                    }

                    if (SysParams.AllowGetWXPrice)
                    {
                        //微信平台价格获取
                        url = string.Format("https://pe.3.cn/prices/mgets?origin=5&skuids={0}", skuids);
                        BatchParse(url, WarePriceType.WxPrice);
                    }

                    //底价及价格趋势处理
                    foreach (var priceItem in _waresPrice)
                    {
                        GetMinPriceSrc(priceItem);
                        GetPriceTrend(priceItem);
                    }
                    ResultItems = _waresPrice;

                }
                catch (Exception ex)
                {
                    Faster.XLogErr(ex.Message);
                }
            }
            Statu = EnumGatherStatu.End;
            Faster.XLogInfo(string.Format("批量采集价格{0}更新结束", Name));
        }

        private JdWarePrice GetMinPriceSrc(double price1, double price2, double price3, double price4)
        {
            JdWarePrice tmpJDPrice = new JdWarePrice();
            tmpJDPrice.p = price1.ToString();
            tmpJDPrice.src = "京东";
            //加入double数组
            double[] listPrice = new double[4];
            listPrice[0] = price1;
            listPrice[1] = price2;
            listPrice[2] = price3;
            listPrice[3] = price4;

            //存储临时的需要冒泡的值
            double tempPrice = listPrice.Max();

            for (int i = 0; i < listPrice.Length; i++)
            {
                //当值为0或-1时，取最大值代替
                if (listPrice[i] == 0 || listPrice[i] == -1)
                {
                    listPrice[i] = tempPrice;
                }
            }

            //tempPrice = listPrice.Min();

            tempPrice = listPrice[0];
            //价格索引，用于判断是哪个平台价格最低
            int tempIndex = 0;
            //从数组的第一个值遍历到倒数第二个值
            for (int i = 1; i < listPrice.Length; i++)
            {
                if (listPrice[i] < tempPrice)
                {
                    tempPrice = listPrice[i];
                    tempIndex = i;
                }
                ////从比i大1的值开始遍历到结束
                ////这里比较的总是比i大的值，因为之前的值已经冒泡完成
                //for (int j = i + 1; j < listPrice.Length; j++)
                //{
                //    //如果前一个值大于后一个值，他们交换位置
                //    if (listPrice[i] > listPrice[j])
                //    {
                //        //交换位置
                //        tempPrice = listPrice[i];
                //        listPrice[i] = listPrice[j];
                //        listPrice[j] = tempPrice;
                //    }
                //}
            }
            switch (tempIndex)
            {
                case 0:
                    tmpJDPrice.src = "京东";
                    break;
                case 1:
                    tmpJDPrice.src = "手机";
                    break;
                case 2:
                    tmpJDPrice.src = "QQ";
                    break;
                case 3:
                    tmpJDPrice.src = "微信";
                    break;
            }
            tmpJDPrice.p = tempPrice.ToString();

            return tmpJDPrice;
        }

        /// <summary>
        /// 获取当次采集最小值
        /// </summary>
        /// <param name="jdWarePrice"></param>
        private void GetMinPriceSrc(JdWarePriceCache jdWarePrice)
        {
            if (jdWarePrice == null) return;
            jdWarePrice.MinPrice = 0;
            jdWarePrice.MinPriceSrc = "京东";
            //加入double数组
            double[] listPrice = new double[4];
            listPrice[0] = jdWarePrice.WebPrice;
            listPrice[1] = jdWarePrice.AppPrice;
            listPrice[2] = jdWarePrice.QqPrice;
            listPrice[3] = jdWarePrice.WxPrice;

            //存储临时的需要冒泡的值
            double tempPrice = listPrice.Max();
            //获取当前最大值
            jdWarePrice.MaxPrice = tempPrice;
            if (jdWarePrice.LastMaxPrice < jdWarePrice.MaxPrice)
            {
                jdWarePrice.LastMaxPrice = jdWarePrice.MaxPrice;
            }

            for (int i = 0; i < listPrice.Length; i++)
            {
                //当值为0或-1时，取最大值代替
                if (listPrice[i] == 0 || listPrice[i] == -1)
                {
                    listPrice[i] = tempPrice;
                }
            }

            tempPrice = listPrice[0];
            //价格索引，用于判断是哪个平台价格最低
            int tempIndex = 0;
            //从数组的第一个值遍历到倒数第二个值
            //不用listPrice.Min是因为需要知道序号来判断来源
            for (int i = 1; i < listPrice.Length; i++)
            {
                if (listPrice[i] < tempPrice)
                {
                    tempPrice = listPrice[i];
                    tempIndex = i;
                }
                
                //从比i大1的值开始遍历到结束
                //这里比较的总是比i大的值，因为之前的值已经冒泡完成
                //for (int j = i + 1; j < listPrice.Length; j++)
                //{
                //    //如果前一个值大于后一个值，他们交换位置
                //    if (listPrice[i] > listPrice[j])
                //    {
                //        //交换位置
                //        tempPrice = listPrice[i];
                //        listPrice[i] = listPrice[j];
                //        listPrice[j] = tempPrice;
                //    }
                //}
            }
            switch (tempIndex)
            {
                case 0:
                    jdWarePrice.MinPriceSrc = "京东";
                    break;
                case 1:
                    jdWarePrice.MinPriceSrc = "手机";
                    break;
                case 2:
                    jdWarePrice.MinPriceSrc = "QQ";
                    break;
                case 3:
                    jdWarePrice.MinPriceSrc = "微信";
                    break;
            }
            jdWarePrice.MinPrice = tempPrice;
            jdWarePrice.LastMinPrice = jdWarePrice.LastMinPrice > tempPrice ? tempPrice : jdWarePrice.LastMinPrice;

        }
        /// <summary>
        /// 获取价格趋势
        /// </summary>
        /// <param name="jdWarePrice"></param>
        private void GetPriceTrend(JdWarePriceCache jdWarePrice)
        {
            if (jdWarePrice == null) return;
            jdWarePrice.PriceTrend = "未知";
            if (jdWarePrice.LastPrice == 0) return;

            if (jdWarePrice.MinPrice < jdWarePrice.TodayPrevPrice)
            {
                jdWarePrice.PriceTrend = "走低";
            }
            if (jdWarePrice.MinPrice > jdWarePrice.TodayPrevPrice)
            {
                jdWarePrice.PriceTrend = "涨价";
            }
            if (jdWarePrice.MinPrice == jdWarePrice.TodayPrevPrice )
            {
                jdWarePrice.PriceTrend = jdWarePrice.MinPrice == jdWarePrice.LastPrice ? "持平" : jdWarePrice.MinPrice > jdWarePrice.LastPrice ? "涨价" : "走低";
            }
        }

        private bool _isWebErr = false;
        /// <summary>
        /// 批价格解析
        /// </summary>
        /// <param name="url">访问网址</param>
        /// <param name="src">价格来源</param>
        [DisplayName("批价格解析")]
        private void BatchParse(string url, WarePriceType src)
        {
            try
            {
                string price = HttpHelper.GetResponseGBK(url, "get", string.Empty);
                if (string.IsNullOrEmpty(price) || price.IndexOf("error", StringComparison.Ordinal) >= 0)
                {
                    _isWebErr = true;
                    Faster.XLogInfo("获取价格失败!!!");
                    //获取价格失败则退出
                    return;
                }

                //网页价格
                List<JdWarePrice> jdPrices = JsonConvert.DeserializeObject<List<JdWarePrice>>(price);
                if (jdPrices != null && jdPrices.Count > 0)
                {
                    foreach (var item in jdPrices)
                    {
                        string pid = item.id.IndexOf('J') >= 0 ? item.id.Replace("J_", "") : item.id;
                        JdWarePriceCache tmpWare = _waresPrice.Find(t => t.Skuid == pid);
                        if (tmpWare == null)
                        {
                            tmpWare = new JdWarePriceCache {Skuid = pid};
                            _waresPrice.Add(tmpWare);
                        }
                        double rtnPrice = 0;
                        double.TryParse(item.p, out rtnPrice);
                        if (rtnPrice <= 0)
                        {
                            Faster.XLogInfo("当前价格为0");
                        }

                        switch (src)
                        {
                            case WarePriceType.WebPrice:
                                //如果日期不等 或者价格不等
                                tmpWare.IsWebChange = tmpWare.PriceGatherDate.Date != DateTime.Now.Date || tmpWare.WebPrice != rtnPrice;
                                tmpWare.WebPrice = rtnPrice;
                                if (rtnPrice <= 0)
                                {
                                    Faster.XLogInfo(string.Format("当前商品网页价格为{0}", rtnPrice));
                                }
                                break;
                            case WarePriceType.AppPrice:
                                tmpWare.IsAppChange = tmpWare.PriceGatherDate.Date != DateTime.Now.Date || tmpWare.AppPrice != rtnPrice;
                                tmpWare.AppPrice = rtnPrice;
                                if (rtnPrice <= 0)
                                {
                                    Faster.XLogInfo(string.Format("当前商品手机价格为{0}", rtnPrice));
                                }
                                break;
                            case WarePriceType.QQPrice:
                                tmpWare.IsQqChange = tmpWare.PriceGatherDate.Date != DateTime.Now.Date || tmpWare.QqPrice != rtnPrice;
                                tmpWare.QqPrice = rtnPrice;
                                if (rtnPrice <= 0)
                                {
                                    Faster.XLogInfo(string.Format("当前商品QQ价格为{0}", rtnPrice));
                                }
                                break;
                            case WarePriceType.WxPrice:
                                tmpWare.IsWxChange = tmpWare.PriceGatherDate.Date != DateTime.Now.Date || tmpWare.WxPrice != rtnPrice;
                                tmpWare.WxPrice = rtnPrice;
                                if (rtnPrice <= 0)
                                {
                                    Faster.XLogInfo(string.Format("当前商品微信价格为{0}", rtnPrice));
                                }
                                break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Faster.XLogErr(ex.Message);
            }

        }
    }

}
